﻿#define _CRT_SECURE_NO_WARNINGS 1

#include "Contact.h"


void CheckCapacity(contact* pc)
{
	//增容
	if (pc->count == pc->capacity)
	{
		PoInfo* ptr = (PoInfo*)realloc(pc->data, sizeof(PoInfo) * (pc->capacity + INC_SZ));//增加容量
		if (ptr == NULL)
		{
			printf("CheckCapacity: %s", strerror(errno));
			exit(0);
		}
		else
		{
			pc->data = ptr;//将realloc申请到的空间给pc->data
			pc->capacity += INC_SZ;
			printf("增容成功！\n");
		}
	}
}

void LoadContact(contact* pc)
{
	assert(pc);
	FILE* pfRead = fopen("Contact.txt", "r");
	if (pfRead == NULL)
	{
		perror("LoadContact");
		exit(0);
	}
	int i = 0;
	while (fgetc(pfRead) != '\n');//将文件指针移动到表头末尾
	int leap = ftell(pfRead);//计算文件指针的偏移量
	fseek(pfRead, leap, SEEK_SET);//将文件指针后移，跳过表头，只读取数据
	while (!feof(pfRead))
	{
		CheckCapacity(pc);//将文件中的数据读取到通讯录中，首先要判断通讯录的容量是否能够放下，放不下时进行增容
		fscanf(pfRead, "%10s\t%4d\t  %6s\t%12s%20s\n", pc->data[i].name,
			&(pc->data[i].units),
			pc->data[i].QQ,
			pc->data[i].tele,
			pc->data[i].addr);
		pc->count++;//每读取一个信息，联系人增加一个
		i++;
	}
	fclose(pfRead);
	pfRead = NULL;
}


//动态版本
void InitContact(contact* pc)
{
	pc->count = 0;//通讯录初始人数
	pc->data = (PoInfo*)calloc(DEFAULT_SZ, sizeof(PoInfo));//申请一块初始化的空间（大小为DEFAULT_SZ）
	if (pc->data == NULL)
	{
		perror("InitContact");//没有开辟成功，结束程序
		exit(0);
	}
	pc->capacity = DEFAULT_SZ;//申请完成后，将通讯录容量赋值为初始大小
	LoadContact(pc);//将文件中的信息加载到通讯录中
}

//释放空间
void DestroyContact(contact* pc)
{
	free(pc->data);
	pc->data = NULL;
}



//动态版本
void AddContact(contact* pc)
{
	assert(pc);//进行断言防止pc为空指针，它的头文件为<assert.h>
	//增容
	CheckCapacity(pc);
	//写入信息
	printf("请输入姓名：>");
	scanf("%s", pc->data[pc->count].name);
	printf("请输入单位：>");
	scanf("%d", &(pc->data[pc->count].units));
	printf("请输入QQ：>");
	scanf("%s", pc->data[pc->count].QQ);
	printf("请输入电话：>");
	scanf("%s", pc->data[pc->count].tele);
	printf("请输入地址：>");
	scanf("%s", pc->data[pc->count].addr);
	pc->count++;
	printf("增加成功！\n");
}

void ShowContact(const contact* pc)
{
	if (pc->count > 9)
	{
		system("cls");
	}
	int i = 0;
	printf("%10s\t%5s\t%10s\t%12s\t%20s\n", "姓名", "单位", "QQ", "电话", "地址");//打印一个表头在屏幕上
	for (i = 0; i < pc->count; i++)
	{
		printf("%10s\t%5d\t%10s\t%12s\t%20s\n", pc->data[i].name,
												pc->data[i].units,
												pc->data[i].QQ,
												pc->data[i].tele, 
												pc->data[i].addr);
		
	}
}

int FindContact(const contact* pc, char name[])
{
	assert(pc);
	int move = 0;
	for (move = 0; move < pc->count; move++)
	{
		if (strcmp(pc->data[move].name, name) == 0)
			return move;//找到目标联系人，返回其下标
	}
	return -1;
}

void DelContact(contact* pc)
{
	assert(pc);
	if (pc->count == 0)
	{
		printf("通讯录为空，无要删除的联系人！\n");
		return;
	}
	char name[20];
	printf("请输入要删除联系人的姓名：>");
	scanf("%s", name);
	//删除
	int pos = FindContact(pc, name);//先找到该联系人
	int move = 0;
	for (move = pos; move < pc->count-1; move++)//注意防止栈溢出
	{
		pc->data[move] = pc->data[move + 1];//后面的元素向前覆盖
	}
	pc->count--;//联系人减少
	printf("删除成功！\n");
}

void SearchContact(const contact* pc)
{
	char name[20];
	printf("请输入你要查找联系人的姓名：>");
	scanf("%s", name);
	int pos = FindContact(pc, name);
	if (pos == -1)
	{
		printf("未查找到该联系人!\n");
		return;
	}
	else
	{
		printf("%10s\t%5s\t%10s\t%12s\t%20s\n", "姓名", "单位", "QQ", "电话", "地址");//打印一个表头，要注意打印形式
		printf("%10s\t%5d\t%10s\t%12s\t%20s\n", pc->data[pos].name,
			pc->data[pos].units,
			pc->data[pos].QQ,
			pc->data[pos].tele,
			pc->data[pos].addr);
	}
}
void ModifyContact(contact* pc)
{
	char name[20];
	printf("请输入你要修改联系人的姓名\n");
	scanf("%s", name);
	int pos = FindContact(pc, name);//先找到该联系人
	if (pos == -1)
	{
		printf("未查找到该联系人!\n");
		exit(0);
	}
	else
	{
		printf("请输入姓名：>");
		scanf("%s", pc->data[pos].name);
		printf("请输入单位：>");
		scanf("%d", &(pc->data[pos].units));
		printf("请输入QQ：>");
		scanf("%s", pc->data[pos].QQ);
		printf("请输入电话：>");
		scanf("%s", pc->data[pos].tele);
		printf("请输入地址：>");
		scanf("%s", pc->data[pos].addr);
		printf("修改成功!\n");
	}
	
}

int CmpByName(const void* e1, const void* e2)
{
	return strcmp(((PoInfo*)e1)->name, ((PoInfo*)e2)->name);
}
void SortContact(contact* pc)//排序，利用qsort函数
{
	assert(pc);
	qsort(pc->data, pc->count, sizeof(PoInfo), CmpByName);
}

void SaveContact(contact* pc)
{
	FILE* pfWrite = fopen("Contact.txt", "w");
	if (pfWrite == NULL)
	{
		perror("SaveContact");
		exit(0);
	}
	int i = 0;
	fprintf(pfWrite, "%-10s\t%5s\t%10s\t%12s\t %20s\n", 
		"姓名", "单位", "QQ", "电话", "地址");
	for (i = 0; i < pc->count; i++)
	{
		fprintf(pfWrite, "%-10s\t%4d\t  %6s\t%12s%20s\n", pc->data[i].name,
			pc->data[i].units,
			pc->data[i].QQ,
			pc->data[i].tele,
			pc->data[i].addr);
	}
	fclose(pfWrite);
	pfWrite = NULL;
}
